﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Xml;
using Common;
using GMap.NET;
using GMap.NET.MapProviders;
using GMap.NET.WindowsForms;
using GMap.NET.WindowsForms.Markers;
using Model;
using System.Diagnostics;

namespace BusStationClient
{
    public unsafe partial class MainForm : Form
    {

        private UdpServer _server;


        private bool _isListen;
        private GMapOverlay _overLayBus;
        private GMapOverlay _overLayLineAndStations;
        private GMapOverlay _oveLayMyLocation;
        private IPEndPoint _serverPoint;
        private byte[] _searchBusCommand;
        private int _updateSleepTime = 10000;
        private Hashtable BusList = Hashtable.Synchronized(new Hashtable());
        readonly System.Windows.Forms.Timer _timerPerf = new System.Windows.Forms.Timer();

        private double _clientVersion = 2.07d;
        private string _strAd = "";
        readonly System.Windows.Forms.Timer _timerAd = new System.Windows.Forms.Timer();

        private DataTable _dtStationList;
        readonly DrawBusLineImage drawBusLineImage = new DrawBusLineImage();
        public Color[] LineColors = new Color[4];
        private bool _isUpdating = false;


        private double offsetLat = -0.002780d;
        private double offsetLng = 0.004999d;

        private ControlCard _controlCard;
        private int[] _controlConfig;
        readonly System.Media.SoundPlayer _player = new System.Media.SoundPlayer(Properties.Resources.waring);

        private string _warmingCallNumber = "18627704749";
        private string _currentStation = "南大红绿灯";
        private string _cameraComPort = "COM1";
        private string _controlCardComPort = "COM2";
        private int _cameraSpaceTime = 600;//摄像头拍图间隔时间 单位为秒        
        private bool _isLinkinternet = true;
        readonly System.Windows.Forms.Timer _timerTimeNow = new System.Windows.Forms.Timer();

        private string _phoneNumeber = "100000000001";


        #region ImportWoDll
        //隐藏鼠标指针
        [DllImport("user32.dll", EntryPoint = "ShowCursor", CharSet = CharSet.Auto)]
        public extern static void ShowCursor(int status);

        //watchdog dll
        [DllImport("kernel32.dll")]
        private extern static IntPtr LoadLibrary(String DllName);

        [DllImport("kernel32.dll")]
        private extern static IntPtr GetProcAddress(IntPtr hModule, String ProcName);

        [DllImport("kernel32")]
        private extern static bool FreeLibrary(IntPtr hModule);

        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        private delegate bool InitializeWinIoType();

        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        private delegate bool GetPortValType(UInt16 PortAddr, UInt32* pPortVal, UInt16 Size = 1);

        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        private delegate bool SetPortValType(UInt16 PortAddr, UInt32 PortVal, UInt16 Size = 1);

        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        private delegate bool ShutdownWinIoType();

        IntPtr hMod;
        #endregion

        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {

            InitConfig();
            // this.TopMost = false;
            Init();
            IniStationGpsInfo();
            DrawRouteOnMap();

            ShowCursor(0);
            Thread threadIniWatchDog = new Thread(IniWatchDog) { IsBackground = true };
            threadIniWatchDog.Start();
      
            Thread thread = new Thread(SendCommandToSearchBus);
            thread.IsBackground = true;
            thread.Start();
            Thread threadCompareVersion = new Thread(SendCommandForVersion);
            threadCompareVersion.Start();
            threadCompareVersion.IsBackground = true;
            Thread threadControlCard = new Thread(MonitorControlCard);
            threadControlCard.IsBackground = true;
            threadControlCard.Start();

            pictureBox1.Image = drawBusLineImage.DrwaImage(pictureBox1.Width, pictureBox1.Height);

        }


        private void Init()
        {
            for (int i = 1; i <= 4; i++)
            {
                string fileNamePoint = "p" + (i % 4 + 1).ToString() + ".png";
                Bitmap tempPointImg = new Bitmap(fileNamePoint);
                Color c = tempPointImg.GetPixel(tempPointImg.Width / 2, tempPointImg.Height / 2);
                LineColors[i - 1] = c;
            }
            //Form
            this.WindowState = FormWindowState.Maximized;
            label_version.Text = "V" + _clientVersion.ToString("0.00");
            this.BackgroundImage = new Bitmap("main_bg.png");

            //Map            
            MainMap.Manager.Mode = AccessMode.ServerAndCache;
            MainMap.MapProvider = GMapProviders.GoogleChinaMap;
            MainMap.ScalePen.Color = Color.Transparent;
            MainMap.CenterPen.Color = Color.Transparent;

            _overLayLineAndStations = new GMapOverlay("Stations");
            MainMap.Overlays.Add(_overLayLineAndStations);
            _overLayBus = new GMapOverlay("Taxi");
            MainMap.Overlays.Add(_overLayBus);
            _oveLayMyLocation = new GMapOverlay("Location");
            MainMap.Overlays.Add(_oveLayMyLocation);
            MainMap.MaxZoom = 18;
            MainMap.MinZoom = 6;
            string[] position = OperateConfig.GetClinetMapPointAndZoom();
            int zoom = 14;
            double theCenterLat = 29.24828790;
            double theCenterLng = 115.78491210;
            int.TryParse(position[2], out zoom);
            double.TryParse(position[0], out theCenterLat);
            double.TryParse(position[1], out theCenterLng);
            MainMap.Zoom = zoom;
            MainMap.Position = new PointLatLng(theCenterLat, theCenterLng);
            MainMap.DragButton = MouseButtons.Left;

            //在线状态及更新时间
            label_newestUpdateTime.Text = "正在获取信息...";
            _isListen = true;

            //IPEndPoint ipep = new IPEndPoint(IPAddress.Any, ConstParameters.AstPort);
            //IPAddress[] ip = Dns.GetHostAddresses(Dns.GetHostName());
    
            _server = new UdpServer(ConstParameters.AstPort);
            _server.OnReceivedData += server_OnDataReceived;
            _server.Start();



            _timerPerf.Tick += DrawBusOnMap;
            _timerPerf.Enabled = true;
            _timerPerf.Interval = 1;
            _timerPerf.Start();

            label_ad.Text = _strAd;
            _timerAd.Tick += PlayAd;
            _timerAd.Enabled = true;
            _timerAd.Interval = 30;
            _timerAd.Start();

            _timerTimeNow.Tick += ShowTimeNow;
            _timerTimeNow.Enabled = true;
            _timerTimeNow.Interval = 1000;
            _timerTimeNow.Start();

            CameraClass camera = new CameraClass(_cameraComPort, _currentStation);
            camera.TakePhotoSpaceTime = _cameraSpaceTime;
            _controlCard = new ControlCard(_controlCardComPort);
        }

        private void InitConfig()
        {
            #region 配置信息 config
            try
            {
                string[] config = OperateConfig.GetClientConfig();
                int.TryParse(config[2], out _updateSleepTime);
                IPAddress ip = IPAddress.Parse("219.140.165.6");

                if (config[3].Trim('\0') != string.Empty)
                {
                    drawBusLineImage.CurrentStation = config[3].Trim('\0');
                    _currentStation = drawBusLineImage.CurrentStation;
                }
                if (config[4].Trim('\0') != string.Empty)
                {
                    drawBusLineImage.NextStation = config[4].Trim('\0');
                }
                // IPAddress.TryParse(config[0], out ip);
                if (config[7].Trim('\0') != "1")
                {
                    this.TopMost = false;
                }
                string asServerip = config[0];
                bool isIpstr = Regex.IsMatch(asServerip, @"^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$");
                if (isIpstr)
                {
                    ip = IPAddress.Parse(asServerip);
                }
                else
                {
                    try
                    {
                        IPAddress[] ips = Dns.GetHostAddresses(asServerip);
                        ip = ips.Length > 0 ? ips[0] : IPAddress.Parse("219.140.165.6");
                        LogService.WriteDebugLog("解析的" + asServerip + "IP:为" + ip.ToString(), DateTime.Now);
                        if (ips.Length == 0)
                        {
                            LogService.WriteLog(asServerip + "解析域名失败...");
                        }
                    }
                    catch (Exception ex)
                    {
                        LogService.WriteLog(asServerip + "解析域名失败...");
                    }

                }
                if (config[5].Length == 11)
                {
                    _phoneNumeber = "1" + config[5];
                }
                _searchBusCommand = OperateAgreement.GetEmptyBodyMessageData(
                    ConstParameters.CmdGetAllBus, _phoneNumeber);
                _serverPoint = new IPEndPoint(ip, ConstParameters.AstPort);
                _strAd = config[6];
                // double.TryParse(config[7], out _clientVersion);

                //配置告警信息
                _controlConfig = new int[12];
                string[] warmingConfig = OperateConfig.GetClientWarmingConfig();
                if (warmingConfig[2].Length >= 11)
                {
                    _warmingCallNumber = warmingConfig[2];
                }
                string[] outPut = warmingConfig[0].Split(',');
                if (outPut.Length == 8)
                {
                    for (int i = 0; i < 8; i++)
                    {
                        int.TryParse(outPut[i], out _controlConfig[i]);
                    }
                }
                if (warmingConfig[1].Length == 4)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        string s = warmingConfig[1][i].ToString();
                        int.TryParse(s, out _controlConfig[8 + i]);
                    }
                }
                //配置串口信息  
                string[] comconfig = OperateConfig.GetComConfig();
                if (comconfig[0].StartsWith("COM"))
                {
                    _cameraComPort = comconfig[0];
                }
                if (comconfig[1].StartsWith("COM"))
                {
                    _controlCardComPort = comconfig[1];
                }
                int.TryParse(comconfig[2], out _cameraSpaceTime);
            }
            catch (Exception ex)
            {
                LogService.WriteLog("InitConfig异常：" + ex.Message);
            }
            #endregion
        }


        #region  watchdog操作
        private void IniWatchDog()
        {
            Thread.Sleep(30000);
            if (IntPtr.Size == 4)
            {
                hMod = LoadLibrary("WinIo32.dll");
            }
            else if (IntPtr.Size == 8)
            {
                hMod = LoadLibrary("WinIo64.dll");
            }

            if (hMod == IntPtr.Zero)
            {
                Thread thread = new Thread(RestartProgram) { IsBackground = true };
                thread.Start();
                MessageBox.Show("Can't find WinIo dll.\nMake sure the WinIo library files are located in the same directory as your executable file.", "DumpPort", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            IntPtr pFunc = GetProcAddress(hMod, "InitializeWinIo");

            if (pFunc != IntPtr.Zero)
            {
                InitializeWinIoType InitializeWinIo = (InitializeWinIoType)Marshal.GetDelegateForFunctionPointer(pFunc, typeof(InitializeWinIoType));
                bool Result = InitializeWinIo();

                if (!Result)
                {
                    Thread thread = new Thread(RestartProgram) { IsBackground = true };
                    thread.Start();
                    MessageBox.Show("Error returned from InitializeWinIo.\nMake sure you are running with administrative privileges and that the WinIo library files are located in the same directory as your executable file.", "DumpPort", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    FreeLibrary(hMod);
                }
            }
            Active();
            while (true)
            {
                // 网络连接正常时 执行喂狗    断开后重启系统
                if (_isLinkinternet)
                {
                    LogService.WriteDebugLog("FeedDog", DateTime.Now);
                    Active();
                }
                else
                {
                    try
                    {
                        ProcessStartInfo ps = new ProcessStartInfo();
                        ps.FileName = "shutdown.exe";
                        ps.Arguments = "-r -t 1";
                        Process.Start(ps);
                    }
                    catch (Exception ex)
                    {
                        LogService.WriteDebugLog("FeedDog-shutdown" + ex.Message, DateTime.Now);
                    }
                }
                Thread.Sleep(180000);
            }
        }

        private void Active()
        {
            IntPtr pFunc = GetProcAddress(hMod, "SetPortVal");
            SetPortValType SetPortVal = (SetPortValType)Marshal.GetDelegateForFunctionPointer(pFunc, typeof(SetPortValType));
            //IntPtr pFunc = GetProcAddress(hMod, "GetPortVal");
            IntPtr pFunc2 = GetProcAddress(hMod, "GetPortVal");
            GetPortValType GetPortVal = (GetPortValType)Marshal.GetDelegateForFunctionPointer(pFunc2, typeof(GetPortValType));
            //write 87h,01h,55h,55h to the index 2eh for enter the MB PnP mode ,enter superio
            SetPortVal(0x2e, 0x87);
            SetPortVal(0x2e, 0x01);
            SetPortVal(0x2e, 0x55);
            SetPortVal(0x2e, 0x55);
            //set logical device number to index 07h
            SetPortVal(0x2e, 0x07);
            SetPortVal(0x2f, 0x07);
            SetPortVal(0x2e, 0x73);	//复位方式   不使用中断方式
            SetPortVal(0x2f, 0xf1);
            SetPortVal(0x2e, 0x72);
            SetPortVal(0x2f, 0xc0);	//按秒计时
            SetPortVal(0x2e, 0x02);
            SetPortVal(0x2f, 0x02);
            //int_timeout = int_secs;
            //byte timeout = 20;		//启动WDT  ACTIVE
            //SetPortVal(0x73, 0x2e);
            //SetPortVal(timeout, 0x2f);
        }

        private void RestartProgram()
        {
            Thread.Sleep(8000);
            Process.Start(System.Reflection.Assembly.GetExecutingAssembly().Location);
            Environment.Exit(0);
        }
        #endregion
        void server_OnDataReceived(object sender, EventArgs e)
        {
               SocketAsyncEventArgs socketAsyncEventArgs = e as SocketAsyncEventArgs;
               if (socketAsyncEventArgs != null)
               {
                   if (socketAsyncEventArgs.BytesTransferred >= ConstParameters.MhLenth)
                   {
                       byte[] receDataaaa = new byte[socketAsyncEventArgs.BytesTransferred];
                       Array.Copy(socketAsyncEventArgs.Buffer, 0, receDataaaa, 0, receDataaaa.Length);
                       List<byte> receBufferBb = new List<byte>();
                       receBufferBb.AddRange(receDataaaa);

                       if (receDataaaa.Length > ConstParameters.MhLenth)
                       {

                           int receBufferBBindex = 0;
                           int sendflag = -1;
                           int endindex = 0;
                           List<byte> receByteList = new List<byte>();

                           foreach (byte b in receBufferBb)
                           {
                               receBufferBBindex++;
                               if (b == 0x7e) sendflag++;
                               if (sendflag >= 0)
                               {
                                   if (sendflag == 0) { receByteList.Add(b); }
                                   else if (sendflag == 1)
                                   {
                                       receByteList.Add(b);
                                       byte[] receData = receByteList.ToArray();
                                       receByteList.Clear();
                                       sendflag = -1;
                                       endindex = receBufferBBindex;
                                       try
                                       {
                                           byte[] realData = OperateAgreement.RestoreReceData(receData);


                                           if (OperateAgreement.JudgeisCompleteData(realData))
                                           {
                                               ushort messageId = OperateAgreement.GetMessageIdInMessageHead(realData);

                                               if (messageId == ConstParameters.CmdGetAllBusReply)
                                               {
                                                   //_overLayBus.Markers.Clear();

                                                   lock (BusList.SyncRoot)
                                                   {
                                                       #region  获取公交车信息
                                                       Array.Reverse(realData, ConstParameters.MBodySatrtIndex, 2);
                                                       int taxicount = BitConverter.ToInt16(realData, ConstParameters.MBodySatrtIndex);
                                                       for (int i = 0; i < taxicount; i++)
                                                       {
                                                           int startIndex = ConstParameters.MBodySatrtIndex + 2 + i * 83;
                                                           byte[] byteLng = new byte[5];
                                                           Array.Copy(realData, startIndex, byteLng, 0, 5);
                                                           string strlng = CommonRoutine.ByteToBcdString(byteLng);
                                                           double lng = double.Parse(strlng) / Math.Pow(10, 6);
                                                           byte[] byteLat = new byte[5];
                                                           Array.Copy(realData, startIndex + 5, byteLat, 0, 5);
                                                           string strLat = CommonRoutine.ByteToBcdString(byteLat);
                                                           double lat = double.Parse(strLat) / Math.Pow(10, 6);
                                                           string busName = Encoding.GetEncoding("GBK").GetString(realData, startIndex + 10, 8);
                                                           short angle = BitConverter.ToInt16(realData, startIndex + 18);
                                                           byte speed = realData[startIndex + 20];

                                                           byte[] byteImei = new byte[8];
                                                           Array.Copy(realData, startIndex + 21, byteImei, 0, 8);
                                                           string strImei = CommonRoutine.ByteToBcdString(byteImei);

                                                           string updatetime = Encoding.GetEncoding("GBK").GetString(realData, startIndex + 29, 14);
                                                           DateTime d = DateTime.ParseExact(updatetime, "yyyyMMddHHmmss", null);
                                                           string prevStation = Encoding.GetEncoding("GBK").GetString(realData, startIndex + 43, 14);
                                                           string currentStation = Encoding.GetEncoding("GBK").GetString(realData, startIndex + 63, 14);
                                                           //TimeSpan timeSpan = new TimeSpan(DateTime.Now.Ticks - d.Ticks);
                                                           //if (timeSpan.TotalSeconds > 120)
                                                           //    continue;

                                                           BusInfo temp = new BusInfo();
                                                           temp.IMEI = strImei;
                                                           temp.Latitude = lat + offsetLat;
                                                           temp.Longitude = lng + offsetLng;
                                                           temp.BusName = busName;
                                                           temp.Angle = angle;
                                                           temp.Speed = speed;
                                                           temp.UpdateTime = d;
                                                           temp.PreStation = prevStation.Trim();
                                                           temp.CurrentStation = currentStation.Trim();

                                                           BusList[temp.IMEI] = temp;
                                                       }
                                                       #endregion
                                                       List<GMapMarker> delTaxiMarkers = new List<GMapMarker>();
                                                       foreach (GMapMarker gMapMarker in _overLayBus.Markers)
                                                       {
                                                           if (!BusList.Contains(gMapMarker.Tag.ToString()))
                                                           {
                                                               delTaxiMarkers.Add(gMapMarker);
                                                           }
                                                       }

                                                       if (delTaxiMarkers.Count > 0)
                                                       {
                                                           foreach (GMapMarker gMapMarker in delTaxiMarkers)
                                                           {
                                                               GMapMarker marker = gMapMarker;
                                                               this.BeginInvoke(new MethodInvoker(() => _overLayBus.Markers.Remove(marker)));
                                                           }
                                                           delTaxiMarkers.Clear();

                                                       }
                                                   }
                                  

                                               }
                                               if (messageId == ConstParameters.CmdSendAD)
                                               {
                                                   #region 接收广告信息学
                                                   string currentStation = Encoding.GetEncoding("GBK").GetString(realData,
                                                       ConstParameters.MBodySatrtIndex, realData.Length - 19);
                                                   _strAd = currentStation.Trim('\0');
                                                   #endregion
                                               }

                                               if (messageId == ConstParameters.CmdGetClientVersionReply)
                                               {
                                                   #region 接收客户端最新版本号
                                                   double newestVersion = BitConverter.ToDouble(
                                                       realData, ConstParameters.MBodySatrtIndex);
                                                   if (newestVersion > _clientVersion)
                                                   {
                                                       if (_isUpdating == false)
                                                       {
                                                           Process.Start(Application.StartupPath + @"\AutoUpdate.exe");
                                                           _isUpdating = true;
                                                       }
                                                       // Environment.Exit(0);                                                     
                                                   }
                                                   #endregion
                                               }

                                               if (messageId == ConstParameters.CmdGetControlCardConfigReply)
                                               {
                                                   #region 接收控制卡输出端口的关闭时间段
                                                   lock (_controlConfig)
                                                   {
                                                       // LogService.WriteLog("接收到控制卡配置信息");
                                                       try
                                                       {
                                                           byte[] controlCardConfig = new byte[12];
                                                           //_controlConfig = new int[12];                                                
                                                           string output = "";
                                                           string intput = "";
                                                           Array.Copy(realData, ConstParameters.MBodySatrtIndex,
                                                               controlCardConfig, 0, 12);
                                                           for (int i = 0; i < 12; i++)
                                                           {
                                                               int.TryParse(Convert.ToString(controlCardConfig[i], 10),
                                                                            out _controlConfig[i]);
                                                               if (i < 8)
                                                               {
                                                                   output += _controlConfig[i].ToString() + ",";
                                                               }
                                                               else
                                                               {
                                                                   intput += _controlConfig[i].ToString();
                                                               }
                                                           }
                                                           string[] config = new string[3];
                                                           config[0] = output.Remove(output.Length - 1);
                                                           config[1] = intput;
                                                           config[2] = _warmingCallNumber;
                                                           OperateConfig.SaveClientWarmingConfig(config);
                                                           //LogService.WriteLog("保存控制卡配置文件" +
                                                           //    config[0] + "," + config[1] + "," + config[2]);
                                                       }
                                                       catch (Exception ex)
                                                       {
                                                           //LogService.WriteLog("保存控制卡配置文件失败:" + ex.Message);
                                                       }

                                                   }
                                                   #endregion
                                               }

                                           }

                                       }
                                       catch (Exception ex)
                                       {
                                           Console.WriteLine(ex);
                                       }

                                   }
                               }
                           }

                           ArrayList al = new ArrayList();
                           lock (BusList.SyncRoot)
                           {
                               foreach (var obj in BusList.Values)
                               {
                                   al.Add(obj);
                               }
                           }

                           this.BeginInvoke(new MethodInvoker(delegate()
                           {
                               //Console.WriteLine("  pictureBox1.Image = drawBusLineImage.DrwaImage(pictureBox1.Width,");
                               label_newestUpdateTime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                               pictureBox1.Image = drawBusLineImage.DrwaImage(pictureBox1.Width,
                                                                              pictureBox1.Height, al);
                           }));
                           if (endindex > 0)
                           {
                               receBufferBb.RemoveRange(0, endindex);
                           }
                       }

                   }
               }
        }

        //private void UdpReceive()
        //{

        //    while (_isListen)
        //    {
        //        try
        //        {
        //            IPEndPoint endPoint = null;
        //            byte[] receDataaaa = _udpClient.Receive(ref endPoint);
        //            List<byte> receBufferBb = new List<byte>();
        //            receBufferBb.AddRange(receDataaaa);
                

        //        }
        //        catch (Exception ex)
        //        {
        //            Console.WriteLine(ex);
        //            LogService.WriteLog("UdpReceive异常：" + ex.Message);
        //            Thread.Sleep(30000);

        //        }
        //    }

       // }

        private void ShowTimeNow(object sender, EventArgs e)
        {
            #region 显示当期时间

            label_timeNow.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

            #endregion
        }


        private void DrawBusOnMap(object sender, EventArgs e)
        {
            #region 画公交车
            try
            {
                BusInfo temp = new BusInfo();
                lock (BusList.SyncRoot)
                {
                    foreach (BusInfo taxiInfo in BusList.Values)
                    {
                        temp = taxiInfo;
                        break;
                    }

                    if (temp != null && temp.IMEI != null)
                    {
     
                 
                                BusList.Remove(temp.IMEI);
                            
                            GMapMarker g =
                                _overLayBus.Markers.FirstOrDefault(
                                    gMapMarker => gMapMarker.Tag.ToString() == temp.IMEI);
                            if (g != null)
                            {
                                this.BeginInvoke(new MethodInvoker(() => _overLayBus.Markers.Remove(g)));
                            }
                            PointLatLng pointLatLng = new PointLatLng(temp.Latitude, temp.Longitude);
                            Bitmap obj = GetBusBitmapByAngle(temp.Angle);
                            // ArrayList al = new ArrayList { temp.DriverPhoneNumber, temp.TaxiState };                                                                   
                            //GMarkerGoogle gMarker = new GMarkerGoogle(pointLatLng, obj)
                            string title = temp.BusName + "\r\n" + temp.CurrentStation;
                            BusMarker gMarker = new BusMarker(pointLatLng, obj,title)
                            {
                                ToolTipText =
                                    "公交线路：" + temp.BusName +
                                    Environment.NewLine
                                    + "车速：" + temp.Speed +
                                    Environment.NewLine
                                    + "方向" + temp.Angle +
                                    Environment.NewLine
                                   + "IMEI:" + temp.IMEI
                                   + Environment.NewLine
                                   + "当前站：" + temp.CurrentStation
                                   + Environment.NewLine
                                   + "上一站：" + temp.PreStation
                                   + Environment.NewLine
                                    + "更新时间：" +
                                    temp.UpdateTime.ToString("HH:mm:ss") +
                                    Environment.NewLine
                                ,
                                ToolTipMode = MarkerTooltipMode.OnMouseOver,
                                Tag = temp.IMEI
                            };

                            this.BeginInvoke(new MethodInvoker(() => _overLayBus.Markers.Add(gMarker)));
                        
                    }
                }
            }
            catch (Exception ex)
            {
                LogService.WriteLog("DrawBusOnMap 异常" + ex.Message);
            }

            #endregion
        }

        private void SendCommandToSearchBus()
        {
            #region 发送搜车命令
            while (_isListen)
            {
                if (BusList.Count == 0)
                {
                    try
                    {
                        if (TestIsLinkInternet())
                        {
                            linkInternetDt = DateTime.Now;
                        }
                        TimeSpan timeSpan = DateTime.Now - linkInternetDt;
                        if (timeSpan.TotalSeconds > 600)
                        {
                            _isLinkinternet = false;
                            LogService.WriteDebugLog(" _isLinkinternet = false;", DateTime.Now);
                        }
                        else
                        {
                            _isLinkinternet = true;
                        }
                        _clickTick++;
                        if (_clickTick % 6 == 0)
                        {
                            _clickTick = 0;
                            BeginInvoke(new MethodInvoker(() =>
                                    {

                                        MainForm_Click(null, null);
                                        notifyIcon1.ShowBalloonTip(10, " ", " ", ToolTipIcon.Info);
                                    }
                                ));



                        }

                        _server.SendData(_searchBusCommand, _serverPoint);


                    }
                    catch (Exception ex)
                    {
                        Thread.Sleep(30000);
                        LogService.WriteLog("SendCommandToSearchBus异常：" + ex.Message);
                    }
                }
                Thread.Sleep(_updateSleepTime);
            }
            #endregion
        }

        private int _clickTick;

        private DateTime linkInternetDt = DateTime.Now;
        private void SendCommandForVersion()
        {
            #region 发送查询版本号命令 及 控制卡配置信息
            byte[] data = OperateAgreement.GetEmptyBodyMessageData(
                ConstParameters.CmdGetClientVersion, _phoneNumeber);
            byte[] data2 = OperateAgreement.GetEmptyBodyMessageData(
                ConstParameters.CmdGetControlCardConfig, _phoneNumeber);
            while (_isListen)
            {
                Thread.Sleep(70000);
                try
                {

                    _server.SendData(data, _serverPoint);

                    _server.SendData(data2, _serverPoint);
                }
                catch (Exception ex)
                {
                    LogService.WriteLog("发送查询版本号、查询控制卡命令失败：" + ex.Message);
                    Thread.Sleep(60000);
                }

                Thread.Sleep(60 * 60 * 1000);
            }
            #endregion
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            //_udpClient.Close();
        }

        private void MainMap_MouseClick(object sender, MouseEventArgs e)
        {
            if (e == null || e.Button == MouseButtons.Left) return;
            PointLatLng p = MainMap.FromLocalToLatLng(e.X, e.Y);
            label1.Text = p.Lat.ToString();
            label2.Text = p.Lng.ToString();
        }

        private void MainForm_SizeChanged(object sender, EventArgs e)
        {
            if (WindowState == FormWindowState.Minimized)
            {
                return;
            }
            pictureBox1.Image = drawBusLineImage.DrwaImage(pictureBox1.Width, pictureBox1.Height);
        }

        public static Bitmap GetBusBitmapByAngle(int angle)
        {
            #region  根据方向返回公交车图标
            int two;
            if ((angle >= 0 && angle <= 20) || (angle >= 340 && angle <= 360))
            {
                two = 1;
            }
            else if (angle > 20 && angle < 70)
            {
                two = 2;
            }
            else if (angle >= 70 && angle <= 110)
            {
                two = 3;
            }
            else if (angle > 110 && angle < 160)
            {
                two = 4;
            }
            else if (angle >= 160 && angle <= 200)
            {
                two = 5;
            }
            else if (angle > 200 && angle < 250)
            {
                two = 6;
            }
            else if (angle >= 250 && angle <= 290)
            {
                two = 7;
            }
            else if (angle > 290 && angle < 340)
            {
                two = 8;
            }
            else
            {
                two = 9;
            }
            string name = "_2" + two;
            return (Bitmap)Properties.Resources.ResourceManager.GetObject(name);
            #endregion
        }


        public static DataSet CXmlFileToDataSet(string xmlFilePath)
        {
            #region 读取xml文件返回 dataset
            if (!string.IsNullOrEmpty(xmlFilePath))
            {
                string path = xmlFilePath;
                StringReader StrStream = null;
                XmlTextReader Xmlrdr = null;
                try
                {
                    XmlDocument xmldoc = new XmlDocument();
                    //根据地址加载Xml文件
                    xmldoc.Load(path);

                    DataSet ds = new DataSet();
                    //读取文件中的字符流
                    StrStream = new StringReader(xmldoc.InnerXml);
                    //获取StrStream中的数据
                    Xmlrdr = new XmlTextReader(StrStream);
                    //ds获取Xmlrdr中的数据
                    ds.ReadXml(Xmlrdr);
                    return ds;
                }
                catch (Exception e)
                {
                    LogService.WriteLog("CXmlFileToDataSet异常：" + e.Message);
                    throw e;
                }
                finally
                {
                    //释放资源
                    if (Xmlrdr != null)
                    {
                        Xmlrdr.Close();
                        StrStream.Close();
                        StrStream.Dispose();
                    }
                }
            }
            else
            {
                return null;
            }
            #endregion
        }

        #region  在地图上画公交车路线
        private void DrawRouteOnMap()
        {
            DataSet ds1 = CXmlFileToDataSet("route1.xml");
            DrawRoute(ds1, 0);
            DataSet ds2 = CXmlFileToDataSet("route2.xml");
            DrawRoute(ds2, 1);
            DataSet ds3 = CXmlFileToDataSet("route3.xml");
            DrawRoute(ds3, 2);
        }
        private void DrawRoute(DataSet ds, int colorindex)
        {
            if (ds != null)
            {
                try
                {
                    for (int i = 0; i < ds.Tables[0].Rows.Count - 1; i++)
                    {
                        double lat1 = double.Parse(ds.Tables[0].Rows[i]["Lng"].ToString());
                        double lng1 = double.Parse(ds.Tables[0].Rows[i]["Lat"].ToString());
                        double lat2 = double.Parse(ds.Tables[0].Rows[i + 1]["Lng"].ToString());
                        double lng2 = double.Parse(ds.Tables[0].Rows[i + 1]["Lat"].ToString());
                        PointLatLng pointLatLng1 = new PointLatLng(lat1, lng1);
                        PointLatLng pointLatLng2 = new PointLatLng(lat2, lng2);
                        DrawLineBetweenTwoPoint(pointLatLng1, pointLatLng2, colorindex);
                    }
                }
                catch (Exception ex)
                {
                    LogService.WriteLog("DrawRoute异常：" + ex.Message);
                }

            }
        }
        private void DrawLineBetweenTwoPoint(PointLatLng startpoint, PointLatLng endpoint, int colorIndex)
        {
            List<PointLatLng> points = new List<PointLatLng>();
            points.Add(startpoint);
            points.Add(endpoint);
            GMapRoute r = new GMapRoute(points, "");
            Pen pen = new Pen(LineColors[colorIndex], 2);
            r.Stroke = pen;
            _overLayLineAndStations.Routes.Add(r);
        }
        #endregion

        #region  得到站点信息列表
        private void IniStationGpsInfo()
        {
            try
            {
                if (_dtStationList == null)
                {
                    _dtStationList = new DataTable();
                    _dtStationList.Columns.Add("站名");
                    _dtStationList.Columns.Add("经度");
                    _dtStationList.Columns.Add("纬度");
                }
                string[] ar1 = StationInfo.Line1.Split(',');
                string[] ar2 = StationInfo.Line2.Split(',');
                string[] ar3 = StationInfo.Line3.Split(',');
                ArrayList al = new ArrayList();
                al.AddRange(ar1);
                al.AddRange(ar2);
                al.AddRange(ar3);

                object[] alDistinct = al.ToArray().Distinct().ToArray();

                foreach (string s in alDistinct)
                {
                    DataRow dr = _dtStationList.NewRow();
                    dr["站名"] = s;
                    _dtStationList.Rows.Add(dr);
                }
                DataSet ds = CXmlFileToDataSet("s.xml");
                foreach (DataRow dr in _dtStationList.Rows)
                {
                    string name = dr["站名"].ToString();
                    DataRow[] rows = ds.Tables[0].Select("name like '%" + name + "%'");
                    if (!rows.Any())
                    {
                        Console.WriteLine(name);
                    }
                    else
                    {
                        dr["经度"] = rows[0]["Lng"].ToString();
                        dr["纬度"] = rows[0]["Lat"].ToString();
                        double lat;
                        double lng;
                        double.TryParse(dr["经度"].ToString(), out lng);
                        double.TryParse(dr["纬度"].ToString(), out lat);
                        lat = lat + offsetLat;
                        lng = lng + offsetLng;
                        PointLatLng pointLatLng = new PointLatLng(lat, lng);
                        Bitmap obj = Properties.Resources.station_15;
                        if (obj == null) continue;
                        StationMarker gMarker = new StationMarker(pointLatLng, obj, name)
                        {
                            ToolTipText =
                                 name
                            ,
                            ToolTipMode = MarkerTooltipMode.Never,
                        };
                      

                        if (name == _currentStation)
                        { 
                           Bitmap objLocation = Properties.Resources.location_20;
                           gMarker.ToolTipText = "您当前的位置";
                           gMarker.ToolTipMode = MarkerTooltipMode.Always;

                           GMarkerGoogle locMarker = new GMarkerGoogle(pointLatLng, objLocation)
                           {
                              ToolTipMode = MarkerTooltipMode.Never
                           };
                           _oveLayMyLocation.Markers.Add(locMarker);
                        }

                        _overLayLineAndStations.Markers.Add(gMarker);
                    }
                }
            }
            catch (Exception ex)
            {
                LogService.WriteLog("IniStationGpsInfo异常:" + ex.Message);
            }

        }

        public static Bitmap GetStationBitmapByName(string name)
        {
            #region  根据方向返回公交车图标
            string bitname = "_" + name;
            return (Bitmap)Properties.Resources.ResourceManager.GetObject(bitname);
            #endregion
        }


        private DataTable GetStadionGpsByLine(string line)
        {
            string[] stationLists = line.Split(',');
            DataTable dt = _dtStationList.Clone();
            dt.Rows.Clear();

            foreach (string s in stationLists)
            {
                DataRow[] rows = _dtStationList.Select("站名='" + s + "'");
                if (rows.Any())
                {
                    DataRow dr = dt.NewRow();

                    dr["站名"] = rows[0]["站名"].ToString();
                    dr["纬度"] = rows[0]["纬度"].ToString();
                    dr["经度"] = rows[0]["经度"].ToString();
                    dt.Rows.Add(dr);
                }
            }
            return dt;
        }

        //private void button1_Click(object sender, EventArgs e)
        //{
        //    DataTable dt = GetStadionGpsByLine(drawBusLineImage.Line1);
        //    Form2 form = new Form2(dt);
        //    form.ShowDialog();
        //}
        #endregion

        private void PlayAd(object sender, EventArgs e)
        {
            #region 播放广告
            try
            {
                if (label_ad.Text != _strAd)
                {
                    label_ad.Text = _strAd;
                    label_ad.Location = new Point(splitContainer2.Panel2.Location.X
                       + splitContainer2.Panel2.Width, label_ad.Location.Y);
                }

                if (label_ad.Location.X > splitContainer2.Panel2.Location.X - label_ad.Width)
                {
                    label_ad.Location = new Point(label_ad.Location.X - 2, label_ad.Location.Y);
                }
                else
                {
                    label_ad.Location = new Point(splitContainer2.Panel2.Location.X
                        + splitContainer2.Panel2.Width, label_ad.Location.Y);
                }
            }
            catch (Exception ex)
            {
                LogService.WriteLog("播放广告异常：" + ex.Message);
            }

            #endregion
        }


        private void MonitorControlCard()
        {
            #region 监控控制卡输入端口报警 及输出端口开关状态
            while (true)
            {

                if (_controlCard != null)
                {
                    try
                    {

                        lock (_controlCard.obj)
                        {
                            string instate = _controlCard.InPutState;
                            string outstate = _controlCard.OutPutState;
                            if (instate != null && outstate != null)
                            {
                                //if(DateTime.Now.Second  ==0)
                                //{
                                //    LogService.WriteLog("输入端口状态：" + instate);
                                //    LogService.WriteLog("输出端口状态：" + outstate);     
                                //}                           
                            }
                            #region  输入端口报警
                            bool hasWarming = false;
                            if (instate != null)
                            {
                                string currentStation = drawBusLineImage.CurrentStation;
                                currentStation = currentStation.Replace("耀邦", "");

                                string warmingtext = DateTime.Now.ToString("MM月dd日 ") +
                                         currentStation + "站";
                                if (_controlConfig != null)
                                {
                                    for (int i = 0; i < 4; i++)
                                    {
                                        //端口状态报警 且 配置文件中该报警为1                                    
                                        if (instate[i] == '1' &&
                                            _controlConfig[i + 8] == 1)
                                        {
                                            //  LogService.WriteLog("输入端口" + i + "状态为0 报警");
                                            //    hasWarming = true;    

                                            // 在报警状态下 震动报警不再算为报警
                                            //if(!_isWarmingState)
                                            //{
                                            //    hasWarming = true;    
                                            //}                                            
                                            //else
                                            //{
                                            //    if (i != 3)
                                            //        hasWarming = true;
                                            //}                                            
                                            hasWarming = true;
                                            switch (i)
                                            {
                                                case 2:
                                                    warmingtext += "门禁告警！";
                                                    break;
                                                case 3:
                                                    warmingtext += "震动告警！";
                                                    break;
                                                default:
                                                    warmingtext += "未定义告警！";
                                                    break;
                                            }
                                        }
                                    }
                                }
                                warmingtext += DateTime.Now.ToString("MM月dd号HH点mm分ss秒");
                                //有报警 且不为报警状态 则发送消息
                                if (hasWarming && !_isWarmingState)
                                {

                                    string message = UnicomSMS.SendSMS(_warmingCallNumber, warmingtext);
                                    LogService.WriteLog("发送短信内容：" + warmingtext + "    返回信息：" + message);
                                }
                            }

                            #endregion
                            #region 输出端口的定时开关
                            if (outstate != null)
                            {
                                string strHourNow = DateTime.Now.ToString("HH");
                                int hourNow = int.Parse(strHourNow);
                                if (_controlConfig == null) continue;

                                #region 输出端口1按时间开关 -外接显示器电源
                                if (hourNow >= _controlConfig[0] && hourNow < _controlConfig[1])
                                {
                                    if (outstate[0] != '1') //如果端口1不处于打开状态 发送命令开启它
                                    {
                                        _controlCard.SetOutPutState(0x01, 1);
                                        // LogService.WriteLog("端口0在开启时间范围内，且其处于关闭状态，发送命令开启端口0...");
                                    }
                                }
                                else //输出端口1处于闭合时间段内
                                {
                                    if (outstate[0] != '0') //如果端口1不处于闭合状态 发送命令关闭它
                                    {
                                        _controlCard.SetOutPutState(0x02, 1);
                                        //  LogService.WriteLog("端口0在关闭时间范围内，且其处于开启状态，发送命令关闭端口0...");
                                    }
                                }
                                #endregion

                                #region 输出端口2按时间开关 --外接灯管
                                if (hourNow >= _controlConfig[2] && hourNow <= _controlConfig[3])
                                {
                                    if (outstate[1] != '1') //如果端口1不处于打开状态 发送命令开启它
                                    {
                                        _controlCard.SetOutPutState(0x01, 2);
                                    }
                                }
                                else //输出端口1处于闭合时间段内
                                {
                                    if (outstate[1] != '0') //如果端口1不处于闭合状态 发送命令关闭它
                                    {
                                        _controlCard.SetOutPutState(0x02, 2);
                                    }
                                }
                                #endregion

                                #region 输出端口3按时间开关 --外接灯管
                                if (hourNow >= _controlConfig[4] && hourNow < _controlConfig[5])
                                {
                                    if (outstate[2] != '1') //如果端口1不处于打开状态 发送命令开启它
                                    {
                                        _controlCard.SetOutPutState(0x01, 3);
                                        //LogService.WriteLog("端口2在开启时间范围内，且其处于关闭状态，发送命令开启端口2...");
                                    }
                                }
                                else //输出端口1处于闭合时间段内
                                {
                                    if (outstate[2] != '0') //如果端口1不处于闭合状态 发送命令关闭它
                                    {
                                        _controlCard.SetOutPutState(0x02, 3);
                                        //LogService.WriteLog("端口2在开启时间范围内，且其处于关闭状态，发送命令开启端口2...");
                                    }
                                }
                                #endregion

                                #region 输出端口4为喇叭  按输入判断开关 不按时间
                                ////=================输出端口4处于打开时间段内==================
                                //if (hourNow >= _controlConfig[6] && hourNow <= _controlConfig[7])
                                //{
                                //    if (outstate[3] != '1') //如果端口1不处于打开状态 发送命令开启它
                                //    {
                                //        _controlCard.SetOutPutState(0x01, 4);
                                //    }
                                //}
                                //else //输出端口1处于闭合时间段内
                                //{
                                //    if (outstate[3] != '0') //如果端口1不处于闭合状态 发送命令关闭它
                                //    {
                                //        _controlCard.SetOutPutState(0x02, 4);
                                //    }
                                //}
                                #endregion

                                if (hasWarming)
                                {
                                    //有报警而喇叭未开时发命令开启
                                    if (outstate[3] != '1')
                                    {
                                        _controlCard.SetOutPutState(0x01, 4);
                                        _controlCard.SetOutPutState(0x01, 4);
                                        //LogService.WriteLog("输入端有告警，输出端口3未开启，发送命令开启端口Y3...");
                                    }
                                    _isWarmingState = true;
                                }
                                else
                                {
                                    //无报警时 若报警时间不在当前时间的15s以内 则关闭喇叭
                                    //TimeSpan span = DateTime.Now - _warmingTime;
                                    //if (span.TotalSeconds > 15 && outstate[3] != '0')
                                    //{
                                    //    _controlCard.SetOutPutState(0x02, 4);
                                    //    _controlCard.SetOutPutState(0x02, 4);
                                    //    //LogService.WriteLog("输入端无告警，输出端口3未关闭，发送命令关闭端口Y3...");
                                    //}
                                    if (outstate[3] != '0')
                                    {
                                        _controlCard.SetOutPutState(0x02, 4);
                                        _controlCard.SetOutPutState(0x02, 4);
                                        //LogService.WriteLog("输入端无告警，输出端口3未关闭，发送命令关闭端口Y3...");
                                    }
                                    _isWarmingState = false;
                                }
                            }
                            #endregion
                        }
                    }
                    catch (Exception ex)
                    {
                        Thread.Sleep(2 * 1000);
                        LogService.WriteLog("MonitorControlCard异常：" + ex.Message);
                    }
                }
                Thread.Sleep(200);
            }
            #endregion
        }

        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            //_udpClient.Close();
        }

        private bool _isWarmingState; // 标识当前是否处于报警状态

        private bool TestIsLinkInternet()
        {
            #region 检测网络连接是否正常
            try
            {
                Ping pingSender = new Ping();
                string strIP = "www.baidu.com";          //要ping的IP地址     第一种方法本人亲自试验过。可以使用
                PingOptions pingOption = new PingOptions();
                pingOption.DontFragment = true;

                string data = "sendData:g";
                byte[] buffer = Encoding.ASCII.GetBytes(data);
                int timeout = 120;
                PingReply reply = pingSender.Send(strIP, timeout, buffer);
                if (reply.Status == IPStatus.Success)
                {
                    Console.WriteLine("能ping通");
                    LogService.WriteDebugLog("能ping通", DateTime.Now);
                    return true;
                }
                else
                {
                    LogService.WriteDebugLog("不能ping通", DateTime.Now);

                    Console.WriteLine("不能ping通");
                    return false;
                }
            }
            catch (Exception ex)
            {
                LogService.WriteDebugLog("不能ping通     " + ex.Message, DateTime.Now);

                Console.WriteLine("不能ping通");
                return false;
            }
            #endregion
        }

        private void MainForm_Click(object sender, EventArgs e)
        {
            this.Focus();
        }
    }

}
